﻿namespace QuickMail.View.Controls
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Markup;

    using DbWorker.AccessModels;
    using DbWorker.DataModels;

    using QuickMail.BusinessLogic;
    using QuickMail.DataModels;
    using QuickMail.ViewModels;

    using Button = System.Windows.Controls.Button;
    using ListViewItem = System.Windows.Controls.ListViewItem;
    using MouseEventArgs = System.Windows.Input.MouseEventArgs;

    /// <summary>
    /// Form with list of processed messages.
    /// </summary>
    public partial class LettersControl
    {
        #region Fields and events

        public delegate void MessageDbClickedDelegate(LetterVm letterVm);
        public event MessageDbClickedDelegate MessageClicked;

        private readonly LetterAm _letterAm;
        private List<LetterDm> _letterDms;
        public readonly ObservableCollection<LetterVm> CurrentLetters = new ObservableCollection<LetterVm>();

        private readonly FileAm _fileAm;
        private LetterVm _currentLetterVm;

        private GridViewColumnHeader listViewSortCol;
        private SortAdorner listViewSortAdorner;


        #endregion //End fields
        
        public LettersControl()
        {
            InitializeComponent();
            SetCurrentTranslate();
            
            // ReSharper disable once RedundantThisQualifier
            this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);

            _letterAm = new LetterAm(StaticFields.DbConnection);
            _fileAm = new FileAm(StaticFields.DbConnection);
        }

        /// <summary>
        /// Sets the current translation for form elements.
        /// </summary>
        public void SetCurrentTranslate()
        {
            OpenFolderTextBlock.Text = StaticFields.Lang.MainWindow.OpenAttachmentsFolder;
            FromColumn.Content = StaticFields.Lang.MainWindow.FromColumn;
            ToColumn.Content = StaticFields.Lang.MainWindow.ToColumn;
            SubjectColumn.Content = StaticFields.Lang.MainWindow.SubjectColumn;
            DateColumn.Content = StaticFields.Lang.MainWindow.DateColumn;
        }

        /// <summary>
        /// Loads letters relating to the rule.
        /// </summary>
        /// <param name="ruleId"></param>
        public void Load(long ruleId)
        {
            _letterAm.SelectByRule(ruleId, out _letterDms);
            CurrentLetters.Clear();

            foreach (var letterDm in _letterDms)
            {
                List<FileDm> tempFiles;
                _fileAm.SelectByLetter(letterDm.Id, out tempFiles);
                CurrentLetters.Add(new LetterVm(letterDm, tempFiles));
            }

            LettersListView.ItemsSource = CurrentLetters;
        }

        /// <summary>
        /// Searches letters in database.
        /// </summary>
        public void Search(string query)
        {
            _letterAm.Search(query, out _letterDms);
            CurrentLetters.Clear();

            foreach (var letterDm in _letterDms)
            {
                List<FileDm> tempFiles;
                _fileAm.SelectByLetter(letterDm.Id, out tempFiles);
                CurrentLetters.Add(new LetterVm(letterDm, tempFiles));
            }

            LettersListView.ItemsSource = CurrentLetters;
        }

        /// <summary>
        /// Unselect when you click in an empty space.
        /// </summary>
        private void UnselectLetter_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            LettersListView.UnselectAll();
        }

        /// <summary>
        /// Displays a pop-up window with a list of files.
        /// </summary>
        private void ShowAttachments_OnClick(object sender, RoutedEventArgs e)
        {
            if (_currentLetterVm == null)
                return;

            int hoPopup = -30;
            AttachmentsWrapPanel.Children.Clear();
            foreach (var fileMetadata in _currentLetterVm.FileVms)
            {
                AttachmentsWrapPanel.Children.Add(new Button
                {
                    Style = (Style)Resources["FileButtonStyle"],
                    Margin = new Thickness(5, 5, 5, 5),
                    Tag = HelpWorker.GetFileImage(fileMetadata.Extention),
                    Content = fileMetadata.FileName,
                    ToolTip = fileMetadata.FileName,
                    CommandParameter = Path.Combine(StaticFields.ResourcesPath,
                        _currentLetterVm.Id.ToString(CultureInfo.InvariantCulture), fileMetadata.FileName)
                });

                if (hoPopup > -460)
                    hoPopup -= 110;
            }

            AttachmentsPopup.HorizontalOffset = hoPopup;
            AttachmentsPopup.IsOpen = true;
        }

        /// <summary>
        /// Notifies about 2-clicking on the letter.
        /// </summary>
        private void LetterItem_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (MessageClicked != null) 
                MessageClicked(_currentLetterVm);
        }

        /// <summary>
        /// Sets a reference to the current letter when the mouse entry.
        /// </summary>
        private void LetterItem_OnMouseEnter(object sender, MouseEventArgs e)
        {
            _currentLetterVm = ((ListViewItem)sender).Content as LetterVm;
        }

        /// <summary>
        /// Sorts letters by current column.
        /// </summary>
        private void LettersSort_OnClick(object sender, RoutedEventArgs e)
        {
            var column = sender as GridViewColumnHeader;
            if(column == null)
                return;

            string sortBy = column.Tag.ToString();
            if (listViewSortCol != null)
            {
                AdornerLayer.GetAdornerLayer(listViewSortCol).Remove(listViewSortAdorner);
                LettersListView.Items.SortDescriptions.Clear();
            }

            ListSortDirection newDir = ListSortDirection.Ascending;
            if (listViewSortCol == column && listViewSortAdorner.Direction == newDir)
                newDir = ListSortDirection.Descending;

            listViewSortCol = column;
            listViewSortAdorner = new SortAdorner(listViewSortCol, newDir);
            AdornerLayer.GetAdornerLayer(listViewSortCol).Add(listViewSortAdorner);
            LettersListView.Items.SortDescriptions.Add(new SortDescription(sortBy, newDir));
        }

        /// <summary>
        /// Starts the cycle remove the selected emails.
        /// </summary>
        private void DeleteButton_OnClick(object sender, RoutedEventArgs e)
        {
            for (int i = LettersListView.SelectedItems.Count - 1; i >= 0; i--)
            {
                var tempLetterVm = LettersListView.SelectedItems[i] as LetterVm;
                if (tempLetterVm != null)
                    DeleteLetter(tempLetterVm);
            }
        }

        /// <summary>
        /// Deletes the selected letter.
        /// </summary>
        /// <param name="letterVm"></param>
        public void DeleteLetter(LetterVm letterVm)
        {
            CurrentLetters.Remove(letterVm);

            _fileAm.DeleteByLetter(letterVm.Id);
            _letterAm.Delete(letterVm.Id);

            string dirPath = StaticFields.ResourcesPath + letterVm.Id;
            if (Directory.Exists(dirPath))
                Directory.Delete(dirPath, true);
        }

        /// <summary>
        /// Opens folder in the explorer.
        /// </summary>
        private void OpenFolder_OnClick(object sender, RoutedEventArgs e)
        {
            if (_currentLetterVm == null)
                return;

            Process.Start("explorer.exe", Path.Combine
                (StaticFields.ResourcesPath, _currentLetterVm.Id.ToString(CultureInfo.InvariantCulture)));
        }

        /// <summary>
        /// Closes the popup window.
        /// </summary>
        private void ClosePopup_OnClick(object sender, RoutedEventArgs e)
        {
            AttachmentsPopup.IsOpen = false;
        }
    }
}
